package config

import (
	"flag"
	"fmt"
	"os"

	"gitee.com/shoyer/util"

	"gitee.com/shoyer/logger"

	configHandler "github.com/larspensjo/config"
	"github.com/spf13/cast"
)

var (
	configFileString = flag.String("config", "config/deploy/local.config.ini", "set `config` file, default is local.config.ini")
	ip               = flag.String("ip", "127.0.0.1", "set `ip`, default 127.0.0.1")
	port             = flag.String("port", "", "set `port`, 本机调式模式请在/.vscode/launch.json 中设置, 未设置，则默认使用80端口")
	config           = make(map[string]string)
	comma            = ","
)

// Init init config
func Init() {
	flag.Parse()
	common := "config/deploy/config.ini"
	// logger.Debugf("Load config file: %s", common)
	configFileCommon, fileErrorCommon := configHandler.ReadDefault(common)
	if fileErrorCommon != nil {
		logger.Fatalf("Failed to find config file: %s %s", common, fileErrorCommon)
	}

	if configFileCommon.HasSection("default") {
		section, err := configFileCommon.SectionOptions("default")
		if err == nil {
			for _, v := range section {
				options, err := configFileCommon.String("default", v)
				if err == nil {
					config[v] = options
				} else {
					logger.Warn(err)
				}
			}
		} else {
			logger.Warn(err)
		}
	}

	// logger.Debugf("Load config file: %s", *configFileString)
	configFile, fileError := configHandler.ReadDefault(*configFileString)
	if fileError != nil {
		logger.Fatalf("Failed to find config file: %s %s", *configFileString, fileError)
	}

	if configFile.HasSection("default") {
		section, err := configFile.SectionOptions("default")
		if err == nil {
			for _, v := range section {
				options, err := configFile.String("default", v)
				if err == nil {
					config[v] = options
				} else {
					logger.Warn(err)
				}
			}
		} else {
			logger.Warn(err)
		}
	}

	if *ip != "" {
		config["ip"] = *ip
	}

	if *port != "" {
		config["port"] = *port
	}

	if config["port"] == "" {
		config["port"] = "80"
	}
}

// GetConfig get config
func GetConfig() map[string]string {
	return config
}

// GetConfigByKey GetConfigByKey
func GetConfigByKey(key string) string {
	return config[key]
}

// GetProjectName GetProjectName
func GetProjectName() string {
	return config["project-name"]
}

// GetRPCPort GetRPCPort
func GetRPCPort() string {
	return config["rpc-port"]
}

// GetConfigServers GetConfigServers
func GetConfigServers() []string {
	servers := util.Split(config["servers"], comma)

	return servers
}

// GetConfigChinaServers GetConfigChinaServers
func GetConfigChinaServers() []string {
	servers := util.Split(config["china-servers"], comma)

	return servers
}

// ShouldCheckRedisMaintenance 是否检查redis中服务器将要维护的时间
func ShouldCheckRedisMaintenance() bool {
	return util.StringToBool(config["should-check-redis-maintenance"])
}

// GetHeartbeatInterval GetHeartbeatInterval
func GetHeartbeatInterval() uint32 {
	return util.StringToUint32(config["heartbeat-interval"])
}

// GetDataDir GetDataDir
func GetDataDir() string {
	return config["data-dir"]
}

// GetDataVersion GetDataVersion
func GetDataVersion() string {
	return config["data-version"]
}

// GetServiceEmail GetServiceEmail
func GetServiceEmail() string {
	return config["service-email"]
}

// GetMasterIP GetMasterIP
func GetMasterIP() string {
	return config["master-ip"]
}

// GetIP GetIP
func GetIP() string {
	return config["ip"]
}

// GetPort GetPort
func GetPort() int {
	return cast.ToInt(config["port"])
}

// GetRootDir GetRootDir
func GetRootDir() string {
	d, _ := os.Getwd()
	return d
}

// GetPublicDir GetPublicDir
func GetPublicDir() string {
	return config["public-dir"]
}

// GetKeyDir GetKeyDir
func GetKeyDir() string {
	return config["key-dir"]
}

// GetEnv GetEnv
func GetEnv() string {
	return config["env"]
}

func GetRedisIP() string {
	return config["redis-ip"]
}

// GetRedisPort GetRedisPort
func GetRedisPort() string {
	return config["redis-port"]
}

// GetRedisPassword GetRedisPassword
func GetRedisPassword() string {
	return config["redis-password"]
}

// GetRedisDB GetRedisDB
func GetRedisDB() int {
	return util.StringToInt(config["redis-db"])
}

// GetDatabaseUser GetDatabaseUser
func GetDatabaseUser() string {
	return config["database-user"]
}

// GetDatabasePassword GetDatabasePassword
func GetDatabasePassword() string {
	return config["database-password"]
}

// GetDatabaseIP GetDatabaseIP
func GetDatabaseIP() string {
	return config["database-ip"]
}

// GetDatabasePort GetDatabasePort
func GetDatabasePort() string {
	return config["database-port"]
}

// GetDatabaseName GetDatabaseName
func GetDatabaseName() string {
	return config["database-name"]
}

// GetDatabaseDebug GetDatabaseDebug
func GetDatabaseDebug() bool {
	return util.StringToBool(config["database-debug"])
}

// ShouldCheckServerStatus ShouldCheckServerStatus
func ShouldCheckServerStatus() bool {
	return util.StringToBool(config["check-server-status"])
}

// GetPublicKey GetPublicKey
func GetPublicKey() []byte {
	key, err := util.ReadAll(GetKeyDir() + "/rsa_public_key.pem")

	if err != nil {
		logger.Error(err.Error())
		return nil
	}

	return key
}

// GetPrivateKey GetPrivateKey
func GetPrivateKey() []byte {
	key, err := util.ReadAll(GetKeyDir() + "/rsa_private_key.pem")

	if err != nil {
		logger.Error(err.Error())
		return nil
	}

	return key
}

// GetKeyFilePath GetKeyFilePath
func GetKeyFilePath(filename string) string {
	return GetKeyDir() + "/" + filename
}

// GetAdminEmail 获取管理员邮箱
func GetAdminEmail() string {
	return config["admin-email"]
}

func GetDatabaseMode() string {
	return config["database-mode"]
}

func GetMaxIdleConns() int {
	return util.StringToInt(config["max-idle-conns"])
}

func GetMaxOpenConns() int {
	return util.StringToInt(config["max-open-conns"])
}

func GetRedisConnMode() string {
	return config["redis-conn-mode"]
}

func GetLoggerLevel() int {
	lv := config["logger-level"]
	switch lv {
	case "debug":
		return logger.LevelDebug
	case "info":
		return logger.LevelInfo
	case "warn":
		return logger.LevelWarn
	case "error":
		return logger.LevelError
	case "fatal":
		return logger.LevelFatal
	case "none":
		return logger.LevelNone
	default:
		return logger.LevelAll
	}
}

func GetWeixinCorpid(suffix string) string {
	if suffix == "" {
		return GetConfigByKey("weixin-corpid")
	}

	return GetConfigByKey(fmt.Sprintf("weixin-corpid-%s", suffix))
}

func GetWeixinCorpsecret(suffix string) string {
	if suffix == "" {
		return GetConfigByKey("weixin-corpsecret")
	}

	return GetConfigByKey(fmt.Sprintf("weixin-corpsecret-%s", suffix))
}

func GetWeixinAgentId(suffix string) string {
	if suffix == "" {
		return GetConfigByKey("weixin-agent-id")
	}

	return GetConfigByKey(fmt.Sprintf("weixin-agent-id-%s", suffix))
}
